
package gps3;

/**
 *
 * @author Ovy90
 */
public class NPosition {

    NavigationPoint latitude;
    NavigationPoint longitude;

    public NPosition(NavigationPoint latitude, NavigationPoint longitude) {
        this.longitude = longitude;
        this.latitude = latitude;
    }

    public NPosition(double latitudeDMS, double longitudeDMS) {
        this.latitude = new NavigationPoint(latitudeDMS);
        this.longitude = new NavigationPoint(longitudeDMS);
    }

  
    public NPosition(String coord) {
        try {
            String split[] = coord.split(",");
            if (split.length != 2) {
                throw new Exception("Invalid length of coordinate String");
            }

            latitude = new NavigationPoint(split[0]);
            longitude = new NavigationPoint(split[1]);

        } catch (Exception e) {
        }
    }

    NPosition(String string, Object[] arr) {
        for (int i = 0; i < arr.length; i++) {
            Object object = arr[i];
            throw new UnsupportedOperationException("Not yet implemented");
        }
    }

    public double distanceTo(NPosition b) {
        double srcLat = latitude.getValueDMS();
        double dstLat = b.getLatitude().getValueDMS();
        double srcLon = longitude.getValueDMS();
        double dstLon = b.getLongitude().getValueDMS();


        double lat1InRadians = srcLat * (Math.PI / 180.0);
        double lon1InRadians = srcLon * (Math.PI / 180.0);
        double lat2InRadians = dstLat * (Math.PI / 180.0);
        double lon2InRadians = dstLon * (Math.PI / 180.0);

        double deltaLatitude = lat2InRadians - lat1InRadians;
        double deltaLongitude = lon2InRadians - lon1InRadians;

        double a =
                Math.pow(Math.sin(deltaLatitude / 2.0), 2.0) +
                Math.cos(lat1InRadians) * Math.cos(lat2InRadians) *
                Math.pow(Math.sin(deltaLongitude / 2.0), 2.0);

        double c = 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));

        double distance = c * 6367;

        return distance;

    }

    public double bearingTo(NPosition b) {
      
        double lat1 = latitude.getValueDMS();
        double lat2 = b.getLatitude().getValueDMS();
        double lon1 = longitude.getValueDMS();
        double lon2 = b.getLongitude().getValueDMS();

        double dLon = lon1 - lon2;

        double y = Math.sin(dLon) * Math.cos(lat2);
        double x = Math.cos(lat1) * Math.sin(lat2) -
                Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
        double brng = Math.atan2(y, x);

        return brng;
    }

    public CardinalPoint getCardinalPoint(double bearingRad) {
        CardinalPoint ret = null;

        CardinalPoint[] a = CardinalPoint.values();

        double degrees = (180.0 / Math.PI) * bearingRad;

        for (int i = 0; i < a.length; i++) {
            
            if (degrees > ((-168.75) + 22.5 * i) && degrees <= ((-168.75) + (22.5) * (i + 1))) {
                return a[i];
            }
        }

        if (degrees > -180.0 && degrees < -168.75) {
            return a[a.length - 1];
        }

        return ret;
    }

    public NavigationPoint getLatitude() {
        return latitude;
    }

    public void setLatitude(NavigationPoint latitude) {
        this.latitude = latitude;
    }

    public NavigationPoint getLongitude() {
        return longitude;
    }

    public void setLongitude(NavigationPoint longitude) {
        this.longitude = longitude;
    }

    @Override
    public String toString() {
        return latitude + "," + longitude;
    }
}